/**  
* Copyright (c) 2008, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// Nov 17, 2008

package com.sceneworker.util.swing.celleditor;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

import com.myjavautils.swing.SwingComponentFactory;
import com.sceneworker.app.globals.SceneWorkerDialogManager;


/**
 * Utility class to wrap cell editor functionality. Provides 3 abstract functions that must be implemented by sub class.<br />
 * 1. getTableCellEditorComponent : return the cell editor component for the model object
 * 2. getCellEditorValue : return the model object for this cell editor
 * 3. getCustomPanel : returns a panel that will be used as the content for an editor dialog
 * @author noellynch
 *
 */
abstract	public class SceneWorkerCustomCellEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {

	protected		JButton								mcl_edit;
	protected		JDialog								mcl_dialog;
	
	private			boolean								mb_inCell = false;
	private			String								mstr_dlgName;
	
	public	SceneWorkerCustomCellEditor(String str_dlgName) {
		mcl_edit = SwingComponentFactory.makeAButton("");
		mcl_edit.addActionListener(this);
		mcl_edit.setBorderPainted(false);
		mstr_dlgName = str_dlgName;
	}
	
	protected	void	setDialogInCell() {
		mb_inCell = true;
	}
	
	/**
	 * Returns what component to use.
	 */
	abstract	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int row, int column);
	
	/**
	 * Open the editor dialog.
	 */
	public void actionPerformed(ActionEvent cl_e) {
		if(cl_e.getSource() == mcl_edit) {
			mcl_dialog = SceneWorkerDialogManager.inst().makeADialog(mstr_dlgName);
			mcl_dialog.setContentPane(getCustomPanel());
			
			if(mb_inCell) {
				mcl_dialog.setUndecorated(true);
				mcl_dialog.setResizable(false);
				mcl_dialog.setLocation(mcl_edit.getLocationOnScreen());
				//mcl_dialog.pack();
			}
			
			mcl_dialog.pack();
			
			mcl_dialog.addWindowListener(new WindowListener() {

				public void windowActivated(WindowEvent arg0) {fireEditingStopped();}

				public void windowClosed(WindowEvent arg0) {}

				public void windowClosing(WindowEvent arg0) {}

				public void windowDeactivated(WindowEvent arg0) {
					
					fireEditingStopped();
				}

				public void windowDeiconified(WindowEvent arg0) {}

				public void windowIconified(WindowEvent arg0) {}

				public void windowOpened(WindowEvent arg0) {}
			});
			
			mcl_dialog.setVisible(true);
			mcl_dialog.repaint();
		}
	}
	
	/**
	 * Returns the value for the cell.
	 */
	abstract	public Object getCellEditorValue();
	
	/**
	 * Returns wether or not we can edit this cell.
	 */
	@Override
	public boolean isCellEditable(EventObject evt) {
		if(evt instanceof MouseEvent)
			return ((MouseEvent) evt).getClickCount() >= 2;

		return true;
	}
	
	abstract	public	JPanel		getCustomPanel();
}
